package sel.me.mysql.learning.sharding;  
  
  
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;
import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSource;
import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;  
  
  
public class ShardingJdbc {  
      
    public static void main(String[] args) throws SQLException {  
          
        //数据源  
        Map<String, DataSource> dataSourceMap = new HashMap<>(2);  
        dataSourceMap.put("sharding_0", createDataSource("sharding_0"));  
        dataSourceMap.put("sharding_1", createDataSource("sharding_1"));  
          
        DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap);  
          
        //分表分库的表，第一个参数是逻辑表名，第二个是实际表名，第三个是实际库  
        TableRule orderTableRule = new TableRule("t_order", false, Arrays.asList("t_order_0", "t_order_1"), dataSourceRule, null, null, null);  
        TableRule orderItemTableRule = new TableRule("t_order_item", false, Arrays.asList("t_order_item_0", "t_order_item_1"), dataSourceRule, null, null, null);  
          
           
        
        /** 
         * DatabaseShardingStrategy 分库策略 
         * 参数一：根据哪个字段分库 
         * 参数二：分库路由函数 
         * TableShardingStrategy 分表策略 
         * 参数一：根据哪个字段分表 
         * 参数二：分表路由函数 
         *  
         */  
        ShardingRule shardingRule = new ShardingRule(dataSourceRule, Arrays.asList(orderTableRule, orderItemTableRule),  
                Arrays.asList(new BindingTableRule(Arrays.asList(orderTableRule, orderItemTableRule))),  
                new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()),  
                new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()));  
          
          
        DataSource dataSource = new ShardingDataSource(shardingRule);  
        String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=? AND o.order_id=?";  
        try (  
                Connection conn = dataSource.getConnection();  
                PreparedStatement pstmt = conn.prepareStatement(sql)) {  
                pstmt.setInt(1, 10);  
                pstmt.setInt(2, 1001);  
            try (ResultSet rs = pstmt.executeQuery()) {  
                while(rs.next()) {  
                    System.out.println(rs.getInt(1));  
                    System.out.println(rs.getInt(2));  
                    System.out.println(rs.getInt(3));  
                }  
            }  
        }  
    }  
  
  
    /** 
     * 创建数据源 
     * @param dataSourceName 
     * @return 
     */  
    private static DataSource createDataSource(String dataSourceName) {  
        DruidDataSource dds = new DruidDataSource();
        dds.setDriverClassName(com.mysql.jdbc.Driver.class.getName());  
        dds.setUrl(String.format("jdbc:mysql://localhost:3306/%s", dataSourceName));  
        dds.setUsername("root");  
        dds.setPassword("");  
        return dds;  
    }  
  
  
}  